﻿using System.ComponentModel;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace Devonline.Database.MongoDB.Models;

/// <summary>
/// MongoDB 数据库模型基础密文基类
/// </summary>
public class DataSecurityMongoModel : MongoModel, IDataSecurity, IMongoModel, IViewModel, IEntitySet
{
    /// <summary>
    /// 数据加密模式
    /// </summary>
    [BsonElement("encryptionMode"), BsonRepresentation(BsonType.String), DisplayName("数据加密模式")]
    public DataEncryptionMode EncryptionMode { get; set; } = DataEncryptionMode.KeyId;
    /// <summary>
    /// 数据版本号, 用于给数据增加一个变量, 在计算 Hash 值时增加不确定因素
    /// </summary>
    [BsonElement("version")]
    public virtual string Version { get; set; } = KeyGenerator.GetStringKey();
    /// <summary>
    /// 数据 Hash 值, 用于确认数据是否被篡改
    /// </summary>
    [BsonElement("hashCode")]
    public virtual string HashCode { get; set; } = null!;
    /// <summary>
    /// 数据密文, 数据被用户数据密钥加密后的结果
    /// </summary>
    [BsonElement("ciphertext")]
    public virtual string Ciphertext { get; set; } = null!;

    /// <summary>
    /// 计算并设置数据的安全数据: 计算 Hash 值和数据密文, 并返回安全数据
    /// </summary>
    public virtual string Security()
    {
        if (this is IDataSerialize dataSerialize)
        {
            var value = dataSerialize.Serialize();
            HashCode = value.GetHashString();
            return value.GetHashString();
        }
        else if (this is IStringSerialize stringSerialize)
        {
            var value = stringSerialize.Serialize();
            HashCode = value.GetHashString();
            return value;
        }
        else
        {
            var ignores = new string[] { nameof(HashCode).ToCamelCase(), nameof(Ciphertext).ToCamelCase() };
            var fields = this.ToKeyValuePairs().Where(x => !ignores.Contains(x.Key));
            var value = fields.OrderBy(x => x.Key).ToString(AppSettings.DEFAULT_URL_OUTER_SPLITER, AppSettings.DEFAULT_URL_INNER_SPLITER);
            HashCode = value.GetHashString();
            return value;
        }
    }
}